#ifndef SETVIEWERPANEL_H
#define SETVIEWERPANEL_H

#include <QWidget>

#include "collection.h"

class SetViewerPanel : public QWidget
{
    Q_OBJECT

public:
    /** Constructor takes a map and a parent, the map will be what this
     * SetViewerPanel draws, so it cannot be null
     */
    SetViewerPanel(const Collection *map, QWidget *parent = 0);

    /** Overwritten so that we can control how this widget is painted. */
    void paintEvent(QPaintEvent *);

    /** Overwritten so that we can control how this widget interacts when it
     * encounters mouse events
     */
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);

    /** Various needed getters */
    inline GraphicalMF* getHeldSet()             const
                      { return m_collection->getSet(m_held_set); }
    inline int          getHeldSetPos()          const { return m_held_set; }
    inline const Collection*  getDisplayedCollection() const
                      { return m_collection; }

    /** Various needed setters */
    void setDisplayedCollection(const Collection* newMap);

signals:

    /** Signal that is emitted when a point in the Collection that this
     * SetViewerPanel is in control of has been changed
     */
    void pointChanged();
    void setChanged();
    void lineChanged();

private:

    /** Enumerator(s) that will allow for easier error handling. */
    enum { NoSelection = -1 };

    /** Get the horizontal scaling factor and shift factor for this
     * SetViewerPanel based on the Collection of fuzzy sets.
     */
    void getWidthFactors(double& scale, double& shift) const;

    /** Get the vertical lower and upper bounds for this SetViewerPanel based
     * on the Collection of fuzzy sets.
     */
    void getHeightFactors(double& lower, double& upper) const;

    /** Grab a point and set for focus */
    void grabPoint(const int& set, const int& point);

    /** Get the square distance of the two points passed in */
    double getSquareDist(const QPointF& a, const QPointF& b) const;

    /** The fuzzy logic set map thing that this class will display */
    const Collection* m_collection;

    /** Current set and point being modified */
    int m_held_set;
    int m_sets_point;

    /** Whether or not the line is being modified. */
    bool m_held_line;

};

#endif // SETVIEWERPANEL_H
